##
# @file 读测试
# @author BlueBaysalt
# @date 2024/11/17
# @brief 试着读取一个文件内的特定内容
# @attention ‘@ENJ’打印调试后面的标记，帮助定位到打印语句
# #

# 包导入
import re  # 正则表达式

# 常量定义
NOT_EXIST = -1  # 用于find()方法，返回-1表示没找到
# flag标志的值
F_NOT = 0  # “否”标志
F_YES = 1  # "是"标志
F_N_FIND = 0  # “没找到”标志
F_FIND = 1  # “找到”标志

# 定义变量
raw_map_dict = {}  # 未处理的地图数据字典对象

# 文件中数据有多少行
Astar_data_line_count = 20  # a星算法地图数据行数
turn_s_data_line_count = 20  # 自定义转弯速度数据行数
s2c_cen_data_line_count = 20  # 自定义节点到车中心距离数据行数
s2c_cen_pt_data_line_count = 20  # 自定义节点到车中心距离数据行数
tu_an_offset_data_line_count = 20  # 自定义转弯角度偏移数据行数
check_node_s_data_line_count = 20  # 自定义检测节点速度数据行数

# 标志变量定义
Astar_data_flag = F_N_FIND  # 找没找到a星算法地图数据的标志，默认为0，找到为1


def parse_complex_string(s):
    ##
    # @name 解析复杂字符串
    # @para s 字符串
    # @func 去除字符串中的空格和换行符，按逗号进行分隔
    # @return 一个包含多个字符串的列表
    # #

    # 使用正则表达式去除多余的空格和换行符，但保留逗号作为分隔符
    cleaned_string = re.sub(r'[\s\n]+(?=,|$)', '', s)
    # 按逗号分割字符串
    parts = cleaned_string.split(',')
    # 清理每个部分（去除前后的空格和引号等）
    cleaned_parts = [part.strip().strip('"') for part in parts]
    return cleaned_parts


def replace_char(original_string, chars_to_replace, replacement):
    ##
    # @name 替换字符
    # @para original_string 目标字符串
    # @para chars_to_replace 目标字符串中想要被替换的子串
    # @para replacement 用什么字符来替换
    # @func 用指定字符替换字符串中的子串
    # @return 字符串
    # #
    trans_table = original_string.replace(chars_to_replace, replacement)
    return trans_table


def processing_map_dict(raw_dict):
    ##
    # @name 处理地图字典
    # @para 单一维度值的字典，特指map.h中地图数据处理后得到的raw_map_dict
    #       raw_map_dict={(0, 0): ['shan1', 'zhudian', '{', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '}', '{', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '}', '{', '-1.93', '0.00', '}', 'nodes____', '0', '{', '0', '0', '}']}
    # @attention 如何加工的请看代码实现，这个具有独特性，其他字典无法处理
    # @return 返回一个嵌套字典，其内的值全为字符串类型
    # #

    map_dict = {}  # 初始化嵌套字典
    l_brace_index_list = []
    r_brace_index_list = []
    for key, values in raw_dict.items():
        for index in range(len(values)):
            if values[index] == "{":
                l_brace_index_list.append(index)
            elif values[index] == "}":
                r_brace_index_list.append(index)
        point_name = values[0]
        point_type = values[1]
        # 由于“距离”在你的数据中不明确，我们可以选择忽略它或将整个剩余部分作为数据
        # 这里我们假设不直接提取“距离”，而是将剩余部分作为“数据”字段的值（作为字符串列表）
        point_distance = values[l_brace_index_list[0] + 1:r_brace_index_list[0]]  # 第一个大括号包含的是距离信息
        point_speed = values[l_brace_index_list[1] + 1:r_brace_index_list[1]]  # 第二个大括号包含的是速度信息
        point_coordinate = values[l_brace_index_list[2] + 1:r_brace_index_list[2]]  # 第三个大括号包含的是实际坐标
        point_info_1 = values[r_brace_index_list[2] + 1]
        point_info_2 = values[r_brace_index_list[2] + 2]
        point_jump = values[l_brace_index_list[3] + 1:r_brace_index_list[3]]  # 第四个大括号包含的是跳跃信息
        # 创建一个嵌套字典并添加到map_dict中
        map_dict[key] = {
            '名称': point_name,
            '类型': point_type,
            '距离': point_distance,  # 如果需要，可以进一步处理这个字段
            '速度': point_speed,
            '坐标': point_coordinate,
            '信息1': point_info_1,
            '信息2': point_info_2,
            '跳跃': point_jump
        }
    return map_dict


# 打开文件
with open('elaborate_map.h', 'r', encoding='utf-8') as file:
    # global end_index
    # 遍历文件的每一行
    for txt_line in file:
        ########## 寻找地图主要数据 ########## 2024/11/17
        str_is_exist = txt_line.find("map_Square_t")
        # 查看这一行中是否有“map_Square_t”内容
        if str_is_exist != NOT_EXIST:
            # print(str_is_exist)   # @ENJ:打印每行内容里map_Square_t出现的位置
            # 查找一行里第一个“{”的位置
            start_index = txt_line.find('{')
            if start_index == NOT_EXIST:
                continue  # 忽略掉不含‘{’的行
            # 由于存在嵌套大括号，我们需要找到与第一个左大括号相匹配的右大括号
            # 这里我们采用一个计数器来追踪大括号的开闭情况
            brace_count = 1  # 大括号计数
            end_index = 0  # 最后一个“}”的位置
            for position, char in enumerate(txt_line[start_index + 1:], start=start_index + 1):
                if char == '{':
                    brace_count += 1
                elif char == '}':
                    brace_count -= 1
                if brace_count == 0:
                    end_index = position  # end_index记录最后一个“}”的位置
                    break
            # 提取并打印最外层大括号里的内容
            brace_content = txt_line[start_index:end_index + 1]
            # 确定大括号在这一行里闭合，可以先排除注释行，再开始记下有效行里数据对应的行列号
            str_static_index = txt_line.find("static")  # 查找每一行中“static”的位置
            if "//" in txt_line[:str_static_index]:  # 在“static”前查看是否包含“//”
                continue  # 包含注释符则跳过此行内容
            # 定义正则表达式模式
            pattern = r"map_\d{2}_\d{2}"  # 内容为：map_两位数字_两位数字
            # 使用 re.findall() 查找所有匹配的子字符串
            row_col_inf = re.findall(pattern, txt_line)  # 内容为：{ ... }
            # print(row_col_inf)  # @ENJ:打印行列信息
            # print(brace_content)  # @ENJ:打印大括号内的内容
            # 删除brace_content中无用的空格，引号
            data_str_1 = brace_content[1:-1]  # 去掉最前后最后的大括号
            # print(data_str_1) # @ENJ:去掉前后大括号
            data_str_2 = replace_char(data_str_1, " ", "")
            # print(data_str_2) # @ENJ:去掉空格
            data_str_3 = replace_char(data_str_2, "\"", "")
            # print(data_str_3)   # @ENJ:去掉引号
            # 接下来在所有左大括号后加上一个逗号‘,’
            data_str_4 = ''
            last_l_brace_index = 0
            for count, ch in enumerate(data_str_3):
                if ch == "{":
                    data_str_4 = data_str_4 + data_str_3[last_l_brace_index:count + 1] + ','
                    last_l_brace_index = count + 1
            data_str_4 = data_str_4 + data_str_3[last_l_brace_index:]
            # print(data_str_4) #@ENJ
            # 接下来在第三个，第四个右括号“}”前加上逗号“，”
            last_r_brace_index = 0
            r_brace_count = 0
            data_str_5 = ""
            for count, ch in enumerate(data_str_4):
                if ch == "}":
                    r_brace_count += 1
                    if r_brace_count >= 3:
                        data_str_5 = data_str_5 + data_str_4[last_r_brace_index:count] + ','
                        last_r_brace_index = count
            data_str_5 = data_str_5 + '}'
            # print(data_str_5)   # @ENJ
            # 将行列信息和大括号里的内容放入字典对象中
            # 使用正则表达式提取数字
            extracted_numbers = []
            for item in row_col_inf:
                # 查找所有数字序列（\d+ 匹配一个或多个数字）
                matches = re.findall(r'\d+', item)
                # 将匹配到的数字序列（字符串形式）添加到列表中
                extracted_numbers.append(matches)
            # 由于我们知道每个字符串都有两个数字，我们可以将它们转换为整数并分别存储
            row_cols = []
            for nums in extracted_numbers:
                # 转换字符串为整数，并作为元组添加到新列表中
                row_cols.append((int(nums[0]), int(nums[1])))
            # print(row_cols)  # @ENJ:以数字形式打印行列号，如(0, 9)
            # 遍历row_cols和brace_content（假设它们长度相同）
            for row_col in row_cols:
                data = parse_complex_string(data_str_5)
                # 将元组作为键，列表作为值放入字典中
                raw_map_dict[row_col] = data
            # print(raw_map_dict)  # @ENJ:打印未作加工的，以行列号元组为键，地图数据字符串为值的地图数据字典




# 将未加工的地图数据字典进行加工
processed_map_dict = processing_map_dict(raw_map_dict)  # 地图数据最终
# 打印结果
# for key, values in processed_map_dict.items():
#     print(key, ':', values)   # @ENJ


##
# 尝试用字典套字典的方式把数据保存进来
# 例如：
# outer_dict = {
#     'key1': 'value1',
#     'key2': {
#         'subkey1': 'sub_value_1',
#         'subkey2': 'sub_value_2'
#     },
#     'key3': [1, 2, 3]  # 虽然这个例子没有直接展示值也是字典，但展示了字典可以包含列表作为值
# }
#
# 期望的格式如下
# map_dict = {
#     (0,0) : {
#         "每个点的名字": "shan1",
#         "节点类型": "zhudian",
#         "点之间的速度对应的距离": [0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
#         "建议的速度": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#         "实际位置坐标": [-1.93 , 0.00],
#         "结点还是信息点": "nodes____",
#         “是否有门是否能通过”： 0，
#         “跳跃信息”： [0 , 0]，
#     },
#     (2,0) : {
#         "每个点的名字": "QS_pingtai1",
#         "节点类型": "pingtai",
#         "点之间的速度对应的距离": [0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
#         "建议的速度": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#         "实际位置坐标": [0.00 , 0.00]],
#         "结点还是信息点": "nodes____",
#         “是否有门是否能通过”： [0]，
#         “跳跃信息”： [0 , 0]，
#     },
#     (3,0) : {
#         "每个点的名字": "msg",
#         "节点类型": "xinxi__",
#         "点之间的速度对应的距离": [0.40, 0.28, 0.10, 0.10, 0.30, 0.00, 0.00, 0.00, 0.00, 0.00],
#         "建议的速度": [75, 158, 166, 158, 75, 0, 0, 0, 0, 0],
#         "实际位置坐标": [0.00 , 0.00]],
#         "结点还是信息点": "msg_point",
#         “是否有门是否能通过”： [0]，
#         “跳跃信息”： [1 , 0]，
#     },
# }
#
#
# #

# # 解析字符串并保存到列表中
# data = parse_complex_string(raw_map_dict[(0, 0)])
#
# # 将解析后的列表作为值存回字典的对应位置上
# raw_map_dict[(0, 0)] = data

# else:
#     pass
